#ifdef __cplusplus
#include <Box2D/Box2D.h>
#include <stdio.h>
#include "box2d.h"
#include "CppClass.hpp"


void* NewVec2(float x, float y)
{
	b2Vec2 *retVec = new b2Vec2(x,y);
	return (void*)retVec;
}
void Vec2_Set(void* ptr,float x,float y)
{
   ((b2Vec2*)ptr)->Set(x,y);
}
float Vec2_GetX(void* ptr_vec2)
{
  return (float)((b2Vec2*)ptr_vec2)->x;
}
float Vec2_GetY(void* ptr_vec2)
{
  return (float)((b2Vec2*)ptr_vec2)->y;
}
void* CNewCVec2Array(int size,float *XPosArr, float *YPosArr)
{
  b2Vec2 *vertices = new b2Vec2[size];
  for(int i=0;i<size;i++)
	{
    vertices[i].Set(XPosArr[i],YPosArr[i]);
	}
    return (void*)vertices;
}
///////////////////////////////////////World/////////////////////////////////////////////
void* NewWorld(float x,float y)
{
	b2World *retWorld = new b2World(b2Vec2(x,y));
	return (void*)retWorld;
}

void* World_CreateBody(void* ptr_world,void* ptr_bodydef)
{
	return (void*)((b2World*)ptr_world)->CreateBody((b2BodyDef*)ptr_bodydef);
}

void World_Step(void* ptr_world,float dt,int velocityIterations,int positionIterations)
{
  ((b2World*)ptr_world)->Step(dt,velocityIterations,positionIterations);
}

void World_SetContactListener(void* ptr_world,void* ptr_ContactListener)
{
   ((b2World*)ptr_world)->SetContactListener((b2ContactListener*)ptr_ContactListener);
 }
///////////////////////////////////////Body//////////////////////////////////////////////
void* NewBodyDef()
{
  return (void*)new b2BodyDef();
}
void* BodyDef_Get_Position(void* ptr)
{
  return &((b2BodyDef*)ptr)->position;
}
void BodyDef_Set_Type(void* ptr_bodydef,int typ)
{
  ((b2BodyDef*)ptr_bodydef)->type = (b2BodyType)typ;
}

void BodyDef_SetFixedRotation(void* ptr_bodydef,int b)
{
     ((b2BodyDef*)ptr_bodydef)->fixedRotation = b!=0;
}

void* Body_CreateFixture(void* ptr_Body,void* ptr_shape,float density)
{
	return (void*)((b2Body*)ptr_Body)->CreateFixture((b2Shape*)ptr_shape,density);
}
void* Body_CreateFixtureByDef(void* ptr_Body,void* ptr_fixtureDef)
{
	return (void*)((b2Body*)ptr_Body)->CreateFixture((b2FixtureDef*)ptr_fixtureDef);
}
void* Body_GetPosition(void* ptr_Body)
{
  return (void*) &((b2Body*)ptr_Body)->GetPosition();
}
void  Body_SetTransform(void* ptr_Body,float posX,float posY,float angle)
{
  ((b2Body*)ptr_Body)->SetTransform(b2Vec2(posX,posY),angle);
}
float Body_GetAngle(void* ptr_Body)
{
   return (float)((b2Body*)ptr_Body)->GetAngle();
}
void  Body_SetLinearVelocity(void* ptr_Body,void* ptr_vec)
{
  ((b2Body*)ptr_Body)->SetLinearVelocity(*(b2Vec2*)ptr_vec);
}
void* Body_GetLinearVelocity(void* ptr_Body)
{
   return (void*)&(((b2Body*)ptr_Body)->GetLinearVelocity());
}
void  Body_ApplyLinearImpulse(void* ptr_Body,void* ptr_impulse,void* ptr_point,int awake)
{
   ((b2Body*)ptr_Body)->ApplyLinearImpulse(*(b2Vec2*)ptr_impulse,*(b2Vec2*)ptr_point,awake!=0);
}
void* Body_GetWorldCenter(void* ptr_Body)
{
	 return (void*)&(((b2Body*)ptr_Body)->GetWorldCenter());
}

void  Body_SetGravityScale(void* ptr_Body , float scale)
{
  ((b2Body*)ptr_Body)->SetGravityScale(scale);
}
void  Body_SetLinearDamping(void* ptr_Body,float linearDamping)
{
	 ((b2Body*)ptr_Body)->SetLinearDamping(linearDamping);
}
void* Body_GetGetContactList(void* ptr_Body)
{
  return  (void*)((b2Body*)ptr_Body)->GetContactList();
}
///////////////////////////////////////Shape/////////////////////////////////////////////
void* NewPolygonShape()
{
	return (void*)new b2PolygonShape();
}
void* NewEdgeShape()
{
  return (void*)new b2EdgeShape();
}
void  PolygonShape_SetAsBox(void* ptr_PolygonShape,float x,float y)
{
	((b2PolygonShape*)ptr_PolygonShape)->SetAsBox(x,y);
}

void  PolygonShape_SetAsBox4(void* ptr_PolygonShape,float x,float y,void* ptr_vec,float angle)
{
    ((b2PolygonShape*)ptr_PolygonShape)->SetAsBox(x,y,*(b2Vec2*)ptr_vec,angle);
}
void  PolygonShape_Set(void* ptr_PolygonShape,void* ptr_vecArr,int size)
{
	((b2PolygonShape*)ptr_PolygonShape)->Set((b2Vec2*)ptr_vecArr,(int32)size);
}
void  EdgeShape_Set(void* ptr_edgeShape,void* ptr_vec1,void* ptr_vec2)
{
  ((b2EdgeShape*)ptr_edgeShape)->Set(*(b2Vec2*)ptr_vec1,*(b2Vec2*)ptr_vec2);
}

void* NewCircleShape()
{
    return (void*)new b2CircleShape();
}
void  CircleShape_SetRadius(void* ptr_circleShape,float radius)
{
   ((b2CircleShape*)ptr_circleShape)->m_radius = radius;
}
///////////////////////////////////////Fixture/////////////////////////////////////////////
void* NewFixtureDef()
{
	return (void*)new b2FixtureDef();
}
void FixtureDef_Set_Shape(void* ptr_fixtureDef,void* ptr_shape)
{
   ((b2FixtureDef*)ptr_fixtureDef)->shape  = (b2Shape*)ptr_shape;
}
void FixtureDef_Set_Density(void* ptr_fixtureDef,float density)
{
   ((b2FixtureDef*)ptr_fixtureDef)->density  = density;
}
void FixtureDef_Set_Friction(void* ptr_fixtureDef,float friction)
{
   ((b2FixtureDef*)ptr_fixtureDef)->friction  = friction;
}
void FixtureDef_Set_isSensor(void* ptr_fixtureDef,int isSensor)
{
    ((b2FixtureDef*)ptr_fixtureDef)->isSensor  = isSensor!=0;
}
void FixtureDef_Set_UserData(void* ptr_fixtureDef,void* userData)
{
    ((b2FixtureDef*)ptr_fixtureDef)->userData  = userData;
}
void* Fixture_Get_UserData(void* ptr_fixture)
{
   return ((b2Fixture*)ptr_fixture)->GetUserData();
}
///////////////////////////////////////ContactListener//////////////////////////////////////
void* NewGoContactListener(void* ptr_Go)
{
  return (void*)new GoContactListener(ptr_Go);
}

void* Contact_GetManifold(void* ptr_Contact)
{
 return	(void*)((b2Contact*)ptr_Contact)->GetManifold();
}

void* Manifold_GetLocalNormal(void* ptr_Manifold)
{
	 return	(void*)&((b2Manifold*)ptr_Manifold)->localNormal;
}

void* Contact_GetFixtureA(void* ptr_Contact)
{
	return (void*)((b2Contact*)ptr_Contact)->GetFixtureA();
}
void* Contact_GetFixtureB(void* ptr_Contact)
{
	return (void*)((b2Contact*)ptr_Contact)->GetFixtureB();
}
int Contact_GetIsTouching(void* ptr_Contact)
{
	return ((b2Contact*)ptr_Contact)->IsTouching();
}
///////////////////////////////////////B2ContactEdge///////////////////////////////////////
void* ContactEdge_GetContact(void* ptr_ContactEdge)
{
	 return (void*)((b2ContactEdge*)ptr_ContactEdge)->contact;
}
void* ContactEdge_GetNext(void* ptr_ContactEdge)
{
  return (void*)((b2ContactEdge*)ptr_ContactEdge)->next;
}
void* ContactEdge_GetPrev(void* ptr_ContactEdge)
{
	return (void*)((b2ContactEdge*)ptr_ContactEdge)->prev;
}
#endif
